<template>
    <div class="column start">
        <h3 style="margin-top: 5px; margin-bottom: 5px; align-self: center;">
            {{ props.title }}
        </h3>

        <div class="form-row">
            <div class="header">名称</div>
            <n-input class="grow" style="width:0px" v-model:value="props.name" />
        </div>
        
        <div class="form-row">
            <div class="header">位置</div>
            <span class="label">X</span>
            <n-input-number class="grow" style="width:0px" v-model:value="props.x" :show-button="false" />

            <span class="label2">Y</span>
            <n-input-number class="grow" style="width:0px" v-model:value="props.y" :show-button="false" />
        </div>
        <div class="form-row">
            <div class="header">尺寸</div>
            <span class="label">宽</span>
            <n-input-number class="grow" style="width:0px" v-model:value="props.width" :show-button="false" />
            
            <span class="label2">高</span>
            <n-input-number class="grow" style="width:0px" v-model:value="props.height" :show-button="false" />
        </div>
        
        <div class="form-row">
            <div class="header">边距</div>            
            <span class="label">上</span>
            <n-input-number class="grow" style="width:0px" v-model:value="props['pad-top']" :show-button="false" />
            <span class="label2">下</span>
            <n-input-number class="grow" style="width:0px" v-model:value="props['pad-bottom']" :show-button="false" />
        </div>
        <div class="form-row">
            <div class="header"></div>
            <span class="label">左</span>
            <n-input-number class="grow" style="width:0px" v-model:value="props['pad-left']" :show-button="false" />
            <span class="label2">右</span>
            <n-input-number class="grow" style="width:0px" v-model:value="props['pad-right']" :show-button="false" />
        </div>

        
        <div class="form-row">
            <div class="header">边框</div>
            <div style="width:60px">
                <n-input-number v-model:value.number="props['border-width']" :show-button="false" />
            </div>
            <div class="grow" style="height:34px; margin-left:10px">
                <n-color-picker v-model:value="props['border-color']" show-alpha @update:value="props['border-color']=$event" />
            </div>
            
        </div>
        <div class="form-row">
            <div class="header">角半径</div>
            <div style="width:60px">
                <n-input-number v-model:value="props.radius" :show-button="false" />
            </div>
        </div>

        <!-- <div class="form-row">
            <div class="header">层叠</div>        
            <n-input-number class="grow" style="width:0px" v-model:value="props.z" />
        </div>


        <div class="form-row" v-show="using.startValue && using.endValue">
            <div class="header">范围</div>
            <n-input-number class="grow" style="width:0px" v-model:value="props.startValue" />
            <span class="label2">-</span>
            <n-input-number class="grow" style="width:0px" v-model:value="props.endValue" />
        </div>
        
        <div class="form-row" v-show="using.startValue && using.endValue">
            <div class="header4">方向</div>
            <div class="grow">
                <i-switch size="large" false-color="#ff4949" :true-value="1" :false-value="2" v-model:value="props.dir">
                    <span slot="open">水平</span>
                    <span slot="close">垂直</span>
                </i-switch>
            </div>
        </div>

        <div class="form-row" v-show="using.autoHoming && using.autoHoming">
            <div class="header4">自动归位</div>
            <div class="grow">
                <i-switch size="large" :true-value="1" :false-value="0" v-model:value="props.autoHoming">
                    <span slot="open">启用</span>
                    <span slot="close">禁用</span>
                </i-switch>
            </div>
        </div>
        
        <div class="form-row" v-show="using.homeValue">
            <div class="header4">归位位置</div>
            <n-input-number class="grow" style="width:0px" v-model:value="props.homeValue" />
        </div> -->

        
        <div class="form-row">
            <div class="header">前景</div>
            <div class="grow">
                <n-color-picker v-model:value="props['text-color']" show-alpha @update:value="props['text-color']=$event" />
            </div>
        </div>
        
        <div class="form-row">
            <div class="header">背景</div>
            <div class="grow">
                <n-color-picker v-model:value="props['bg-color']" show-alpha @update:value="props['bg-color']=$event" />
            </div>
        </div>

        <div class="form-row" v-if="using.text">
            <div class="header">文本</div>        
            <n-input class="grow" style="width:0px" v-model:value="props.text" type="textarea" rows="2" />
        </div>
        <div class="form-row" v-if="using.text">
            <div class="header">字体</div>   
            <div class="grow">
                <n-select v-model:value="props.font" :options="fonts" />
            </div>    
        </div>
        
        <div class="form-row" v-if="using.text">
            <div class="header4">文本对齐</div>
            <n-radio-group v-model:value="props['text-align']" size="large">
                <n-radio-button key="left" value="left">
                    <n-icon><FormatAlignLeftRound /></n-icon>
                </n-radio-button>
                <n-radio-button key="center" value="center">
                    <n-icon><FormatAlignCenterRound /></n-icon>
                </n-radio-button>
                <n-radio-button key="right" value="right">
                    <n-icon><FormatAlignRightRound /></n-icon>
                </n-radio-button>
            </n-radio-group>
        </div>

        <!-- <div class="form-row">
            <div class="header4">垂直对齐</div>
            <Button class="grow" :type="props.textAlignVertical==0?'primary':'default'" @click="setAlign('Vertical', 0)">上</Button>
            <Button class="grow" :type="props.textAlignVertical==1?'primary':'default'" @click="setAlign('Vertical', 1)">中</Button>
            <Button class="grow" :type="props.textAlignVertical==2?'primary':'default'" @click="setAlign('Vertical', 2)">下</Button>
        </div> -->
    </div>
</template>

<script lang="ts" setup>
import * as lv  from "../../../lvgl"
import WidgetLib from './WidgetLib'
import { ref, reactive, Ref, computed } from 'vue'
import { LvglEditor } from "./LvglEditor";

import {FormatAlignLeftRound, FormatAlignRightRound, FormatAlignCenterRound} from '@vicons/material'

const widget = ref(null) as Ref<lv.Obj|null>
let editor: LvglEditor


const propValues: any = reactive({})

const props: any = reactive({
    title: computed( () => { return widget.value? (WidgetLib as any)[widget.value.constructor.name as string].title: '' }) ,
    name: computed({
        get() { return widget.value?.name } ,
        set(val) {
            if(widget.value) {
                // @todo 
                // 判断重复
                widget.value.name = val as string
            }
        }
    })
})

function useChild(propName: string, widget: lv.Obj) {
    if( (propName=='text' || propName=='text-align') && (widget as any).label instanceof lv.Label ) {
        return (widget as any).label
    }
    else {
        return widget
    } 
}

const propDefines: any = {}
function defineProp(propName: string, isStyle=false, getter?: any, setter?: any, init?:(w:lv.Obj)=>any) {
    if(!getter) {
        getter = () => { return propValues[propName] }
    }
    if(!setter) {
        let setterName = "set" + propName[0].toUpperCase() + propName.substr(1)
        setter = (val:any) => {
            propValues[propName] = val
            if(!widget.value) {
                return
            }
            if(isStyle) {
                let w: lv.Obj = useChild(propName, widget.value)
                w.setStyle(propName, val as any)
            }
            else {
                if( (widget.value as any)[setterName as string]){
                    (widget.value as any)[setterName as string](val)
                }
                // 影响窗体的尺寸
                if(["x","y","width","height","pad-left","pad-right","pad-top","pad-bottom","border-width","font"].includes(propName)) {
                    if(editor) {
                        widget.value.updateLayout()
                        editor.helper.update()
                    }
                }
            }
        }
    }
    if(!init) {
        init = (w:lv.Obj)=>{
            w = useChild(propName, w)
            if(isStyle){
                return w.style(propName)
            }
            if(typeof (w as any)[propName]=='function') {
                return (w as any)[propName]()
            }
        }
    }
    propDefines[propName] = {
        init
    }
    props[propName] = computed({
        get: getter ,
        set: setter
    })
}

function rgba(r:number, g:number, b:number, a:number) {
    return [ new  lv.Color(r,g,b), Math.round(a*255) ]
}
function defineColorStyle(name:string, opaName:string) {
    defineProp(
        name,true, undefined
        // setter
        , (val: string) => {
            propValues[name] = val
            let [color, opa] = eval(val) // val: raga(x,x,x,x)
            widget.value?.setStyle(name, color)
            widget.value?.setStyle(opaName, opa)
        }
        // init
        , (widget:lv.Obj)=>{
            let color = widget.style(name) as lv.Color
            let opa = widget.style(opaName) as number
            opa = opa/255
            return `rgba(${color.r},${color.g},${color.b},${opa.toFixed(2)})`
        }
    )
}

defineProp("x")
defineProp("y")
defineProp("width")
defineProp("height")
defineProp("font")

defineProp("radius", true)
defineProp("pad-left", true)
defineProp("pad-right", true)
defineProp("pad-top", true)
defineProp("pad-bottom", true)

defineProp("radius", true)
defineProp("border-width", true)
defineColorStyle("border-color", 'border-opa')

defineProp("text")
defineProp("text-align", true)
defineColorStyle("text-color", "text-opa")
defineColorStyle("bg-color", "bg-opa")
    
function onWidgetRectChanged(propName:string, val: number) {
    propValues[propName] = val
}

function setWidget(_widget: lv.Obj, _editor: LvglEditor){

    if(widget.value && widget.value!=_widget) {
        widget.value.off("rect-changed-by-editor", onWidgetRectChanged)
    }
    
    widget.value = _widget

    if(_widget) {
        for(let propName in propDefines) {
            // console.log(propName)
            propValues[propName] = propDefines[propName].init(_widget)
        }

        for(let name in using) {
            // console.log(name, (using as any)[name])
            ; (using as any)[name] = typeof((_widget as any)[name]) == 'function'
        }

        _widget.on("rect-changed-by-editor", onWidgetRectChanged)

    }
    editor = _editor
}

const using = reactive({
    text: false ,
})

const fonts = [
    { label: "微软雅黑(中文)", value: 'msyh', } ,
    { label: "m8", value: 'm8', } ,
    { label: "m10", value: 'm10', } ,
    { label: "m12", value: 'm12', } ,
    { label: "m16", value: 'm16', } ,
    { label: "m24", value: 'm24', } ,
    { label: "m32", value: 'm32', } ,
    { label: "m40", value: 'm40', } ,
    { label: "m48", value: 'm48', } ,
]

defineExpose({setWidget})
</script>